use std::any::Any;
use std::fmt;
use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;
use tracing::{trace, debug, info, warn, error};

use protoactor_rs::actor::{Actor, ActorContext, ActorError, DefaultActorContext, PID, Props, RequestContext};
use protoactor_rs::ActorSystem;

// Define a simple message
#[derive(Debug, Clone)]
struct Hello {
    name: String,
}

// Define a simple response
#[derive(Debug, Clone)]
struct HelloResponse {
    message: String,
}

impl fmt::Display for HelloResponse {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.message)
    }
}

// Define a simple actor
struct HelloActor;

#[async_trait]
impl Actor for HelloActor {
    type Context = DefaultActorContext;
    
    async fn receive(&self, ctx: &mut Self::Context, msg: Box<dyn Any + Send>) -> Result<(), ActorError> {
        // 打印消息类型ID，帮助识别
        debug!("HelloActor received message with type_id: {:?}", msg.type_id());
        
        // 提前获取消息的内存布局信息
        let size = std::mem::size_of_val(&*msg);
        let align = std::mem::align_of_val(&*msg);
        
        // Try to downcast the message to Hello
        if let Ok(hello) = msg.downcast::<Hello>() {
            info!("Actor received Hello from: {}", hello.name);
            
            // 创建响应但不发送，只打印
            let response = HelloResponse {
                message: format!("Hello, {}!", hello.name),
            };
            
            // 只打印响应，不尝试发送
            info!("Generated response: {:?}", response);
            
            return Ok(());
        } else {
            // 打印更多信息，帮助调试
            warn!("Failed to downcast message to Hello. Message type: {:?}", std::any::type_name::<Box<dyn Any + Send>>());
            debug!("Message size: {}, align: {}", size, align);
        }
        
        warn!("Actor received unknown message");
        Ok(())
    }
    
    async fn started(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        info!("HelloActor started");
        Ok(())
    }
    
    async fn stopping(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        info!("HelloActor stopping");
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 使用改进后的日志初始化函数，显式设置库和示例的日志级别
    protoactor_rs::logging::init_global_logger(
        Some(tracing::Level::DEBUG),  // 设置protoactor-rs库的日志级别为DEBUG
        Some("hello_actor=debug"),    // 设置当前示例的日志级别为DEBUG
    )?;
    
    // Create an actor system
    let system = ActorSystem::new()?;
    
    // Create props for the actor
    let props = Props::from_producer(|| HelloActor);
    
    // Spawn the actor
    let pid = system.spawn::<HelloActor>(props).await?;
    
    info!("Created actor with PID: {}", pid);
    
    // Send a message to the actor
    system.send(&pid, Hello { name: "World".to_string() }).await?;
    
    // 不使用request方法，而是使用send方法
    system.send(&pid, Hello { name: "RequestResponse".to_string() }).await?;
    
    // 等待一段时间，让消息处理完成
    tokio::time::sleep(Duration::from_millis(500)).await;
    
    info!("All messages sent successfully");
    
    // Stop the actor
    system.stop(&pid).await?;
    
    // Wait a bit for the actor to stop
    tokio::time::sleep(Duration::from_millis(500)).await;
    
    Ok(())
} 